package com.example.xyxwebbackend001.service.impl;

import com.example.xyxwebbackend001.mapper.*;
import com.example.xyxwebbackend001.model.DTO.*;
import com.example.xyxwebbackend001.model.entity.*;
import com.example.xyxwebbackend001.model.enums.TagEnum;
import com.example.xyxwebbackend001.model.vo.ArticleListVO;
import com.example.xyxwebbackend001.model.vo.ArticlePathListVO;
import com.example.xyxwebbackend001.service.CPostsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

@Service
public class CPostsServiceImpl implements CPostsService {
    @Autowired
    private CPOSTSMapper cPostsMapper;

    @Autowired
    private ArticleMapper articleMapper;

    @Autowired
    private ContentBlockMapper contentBlockMapper;

    @Autowired
    private ArticleImageMapper articleImageMapper;
    @Autowired
    private CityMapper cityMapper;

    @Autowired
    private ArticleVideoMapper articleVideoMapper;

    @Override
    public CPosts getPostDetail(Integer id) {
        return cPostsMapper.selectById(id);
    }

    @Override
    public List<ArticleSimpleDTO> getArticlesByCity(String cityId) {
        List<ArticleSimpleDTO> list = articleMapper.selectArticlesByCityId(cityId);
        list.forEach(ArticleSimpleDTO::convertTagToName);
        return list;
//        return  articleMapper.selectArticlesByCityId(cityId);
    }

    @Override
    public Map<String, Object> getArticleDetail(Integer articleId) {
        if (articleId == null) {
            throw new RuntimeException("文章ID不能为空");
        }
        articleMapper.incrementViewCount(articleId);
        ArticleDTO article = articleMapper.selectArticleById(articleId);
        if (article == null) {
            throw new RuntimeException("文章不存在");
        }

        List<ContentBlock> content = contentBlockMapper.selectByArticleId(articleId);
        List<ArticleImage> images = articleImageMapper.selectByArticleId(articleId);
        List<ArticleVideo> videos = articleVideoMapper.selectByArticleId(articleId);
        String cityName = cityMapper.selectById(article.getCityId()).getCityName() + "市";

        return Map.of(
                        "title", article.getTitle(),
                        "content", convertContent(content),
                        "images", processImages(images),
                        "videos", videos,
                        "viewCount", article.getViewCounts(),
                        "cityName", cityName
                );
    }

    private List<Map<String, Object>> convertContent(List<ContentBlock> content) {
        return content.stream().map(item -> {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("type", item.getBlockType().getValue());

            if (item.getBlockType() == ContentBlock.BlockType.LIST && item.getListItems() != null) {
                List<Map<String, String>> processedItems = Arrays.stream(item.getListItems().split("；"))
                        .map(String::trim)
                        .filter(s -> !s.isEmpty())
                        .map(str -> {
                            Map<String, String> itemMap = new LinkedHashMap<>();
                            itemMap.put("content", str);
                            return itemMap;
                        })
                        .collect(Collectors.toList());

                int[] order = {1};
                processedItems.forEach(i -> i.put("orderItem", String.valueOf(order[0]++)));

                map.put("content", processedItems);
            }
            else {
                if (item.getTextContent() != null) {
                    map.put("content", item.getTextContent());
                }
                if (item.getLevel()!= null) {
                    map.put("level", item.getLevel());
                }
            }

            return map;
        }).collect(Collectors.toList());
    }

    private List<Map<String, Object>> processImages(List<ArticleImage> images) {
        return images.stream().map(img -> {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("imageId", img.getImageId());
            map.put("imagePath", img.getImagePath());
            map.put("imageType", img.getImageType().name());
            map.put("altText", img.getAltText());
            map.put("description", img.getDescription());
            return map;
        }).collect(Collectors.toList());
    }

    @Override
    @Transactional
    public Integer publishCPost(ArticleRequestDTO dto) {

        Article article = new Article();
        article.setTitle(dto.getTitle());
        article.setSummary(dto.getDescription());
        article.setCityId(dto.getPlace());
        article.setTags(dto.getTags());
        articleMapper.insert(article);
        int articleId = article.getArtId();
        int num = 1;
        if (articleId != 0) {
            if (dto.getCover() != null) {
                ArticleImage coverImage = new ArticleImage();
                coverImage.setArtId(articleId);
                coverImage.setImagePath(dto.getCover().getImagePath());
                coverImage.setImageType(ArticleImage.ImageType.COVER);
                coverImage.setAltText(dto.getCover().getAltText());
                coverImage.setDescription(dto.getCover().getDescription());
                articleImageMapper.insert(coverImage);
            }
            if (dto.getContent() != null) {
                AtomicInteger orderCounter = new AtomicInteger(1);
                dto.getContent().forEach((blockDTO) -> {
                if ("image".equalsIgnoreCase(blockDTO.getType())) {
                    ArticleImage img = new ArticleImage();
                    img.setArtId(article.getArtId());
                    img.setImagePath(((ImageBlockDTO) blockDTO).getImagePath());
                    img.setImageType(ArticleImage.ImageType.CONTENT);
                    img.setAltText(((ImageBlockDTO) blockDTO).getAltText());
                    img.setDescription(((ImageBlockDTO) blockDTO).getDescription());
                    articleImageMapper.insert(img);
                }else if ("video".equalsIgnoreCase(blockDTO.getType())) {
                    VideoBlockDTO videoDTO = (VideoBlockDTO) blockDTO;
                    ArticleVideo video = new ArticleVideo();
                    video.setArtId(article.getArtId());
                    video.setVideoPath(videoDTO.getVideoPath());
                    video.setDescription(videoDTO.getDescription());
                    articleVideoMapper.insert(video);
                }
                else {
                    ContentBlock block = new ContentBlock();
                    block.setArtId(article.getArtId());
                    block.setOrderNum(orderCounter.getAndIncrement());
                    block.setBlockType(ContentBlock.BlockType.valueOf(blockDTO.getType().toUpperCase()));

                    try {
                        ContentBlock.BlockType blockType = ContentBlock.BlockType.valueOf(blockDTO.getType().toUpperCase());
                        block.setBlockType(blockType);

                        if (blockDTO instanceof HeadingBlockDTO headingDTO) {
                            block.setLevel(headingDTO.getLevel());
                            block.setTextContent(headingDTO.getTextContent());
                        } else if (blockDTO instanceof ParagraphBlockDTO paragraphDTO) {
                            block.setTextContent(paragraphDTO.getTextContent());
                        } else if (blockDTO instanceof ListBlockDTO listDTO) {
                            block.setListItems(String.join("；", listDTO.getListItems()));
                        }
                    } catch (IllegalArgumentException e) {
                        throw new RuntimeException("无效的内容块类型: " + blockDTO.getType());
                    }
                    contentBlockMapper.insert(block);
                }
            });
        }
        }
        return article.getArtId();
    }

    @Override
    public List<ArticleListVO> getCPostsList(String keyword) {
        return articleMapper.selectArticleByKeyword(keyword);
    }

    @Override
    public Integer updateArticleStatus(Integer articleId, Integer status) {
        return articleMapper.updateArticleStatus(articleId, status);
    }

    @Override
    public List<ArticlePathListVO> getArticlePathList(String tags) {
        return Arrays.stream(TagEnum.values())
                .filter(e -> e.getName().equals(tags))
                .findFirst()
                .map(tagEnum -> articleMapper.getArticlePathList(String.valueOf(tagEnum.getCode())))
                .orElse(Collections.emptyList());
    }
}
